package com.caocaog.market.finance.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.caocaog.market.finance.entity.FinanceLine;
import com.caocaog.market.finance.enums.WithdrawStatus;
import com.caocaog.market.finance.service.FinanceLineService;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.GenericController;
import org.jeecg.common.system.domain.QueryRequest;
import org.jeecg.common.system.query.PageGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.online.config.exception.BusinessException;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.util.Assert;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.caocaog.market.finance.entity.FinanceLine.isUpdatableShopPCT;
import static com.caocaog.market.finance.entity.FinanceLine.isUpdatableSitePCT;
import static java.util.stream.Collectors.toMap;

@Slf4j
@Validated
@RestController
@RequestMapping("financeLine")
public class FinanceLineController extends GenericController<FinanceLine, FinanceLineService> {


    @PostMapping("page")
    public Result<IPage<FinanceLine>> queryLinePage(@RequestBody(required = false) FinanceLine financeLine, QueryRequest queryRequest) {
        try {
            Page<FinanceLine> page = PageGenerator.createPageSort(queryRequest);
            String siteId = null;
            String merchantId = null;
            LoginUser currentUser = getLoginUser();
            if (currentUser.getUserType() == 2) {
                siteId = Optional.ofNullable(currentUser.getSiteId()).orElseThrow(() -> new BusinessException("分站用户未绑定分站"));
            } else if (currentUser.getUserType() == 3) {
                merchantId = Optional.ofNullable(currentUser.getMerchantId()).orElseThrow(() -> new BusinessException("商家用户未绑定商家"));
            }
            return Result.OK(service.queryFinanceLinePage(page, Optional.ofNullable(financeLine).orElse(new FinanceLine()), siteId, merchantId));
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("查询提现行分页信息失败, " + e.getMessage());
        }
    }


    @PutMapping("updatePCT") // PCT（percentage 百分比）
    public Result<Integer> updateCommissionPCT(@RequestBody FinanceLine financeLine) {
        try {
            Assert.notNull(financeLine.getSystemPCT(), "系统抽成比例不能为空");
            Assert.notNull(financeLine.getSitePCT(), "分站抽成比例不能为空");
            Assert.isTrue(financeLine.getSystemPCT().add(financeLine.getSitePCT()).compareTo(BigDecimal.ONE) <= 0, "系统抽成比例和分站抽成比例之和不能大于100%");
            FinanceLine financeLineOld = Optional.ofNullable(service.getById(financeLine.getId()))
                    .orElseThrow(() -> new BusinessException("提现行不存在"));
            Assert.isTrue(isUpdatableSitePCT(financeLineOld), "分站提现状态为已经通过审核，不可修改");
            Assert.isTrue(isUpdatableShopPCT(financeLineOld), "商家提现状态为已经通过审核，不可修改");

            return Result.OK(service.updateFinanceLine(new FinanceLine()
                    .setSystemPCT(financeLine.getSystemPCT())
                    .setSitePCT(financeLine.getSitePCT())
                    .calculateShopPCT()
                    .setId(financeLine.getId())));
        } catch (Exception e) {
            throw new RuntimeException("更新提现行抽成比例失败, " + e.getMessage());
        }
    }


    @GetMapping("status")
    public Result<Map<Integer, String>> getWithdrawStatus() {
        return Result.OK(Arrays.stream(WithdrawStatus.values()).filter(status ->
                status.getTypes().contains(WithdrawStatus.Type.LINE)
        ).collect(toMap(WithdrawStatus::getCode, WithdrawStatus::getName)));
    }


    @GetMapping(value = "/getList{groupId}")
    public List<FinanceLine> getList(@NotNull @PathVariable Long groupId) {
        try {
            return service.getFinanceLineListByGroupId(groupId);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("查询提现行分页信息失败, " + e.getMessage());
        }

    }


    @GetMapping(value = "/export")
    public ModelAndView exportXls(@RequestBody(required = false) FinanceLine financeLine, QueryRequest queryRequest) {
        try {
            ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
            Page<FinanceLine> page = PageGenerator.createPageSort(queryRequest);
            String siteId = null;
            String merchantId = null;
            LoginUser currentUser = getLoginUser();
            queryRequest.setPageSize(-1);
            if (currentUser.getUserType() == 2) {
                siteId = Optional.ofNullable(currentUser.getSiteId()).orElseThrow(() -> new BusinessException("分站用户未绑定分站"));
            } else if (currentUser.getUserType() == 3) {
                merchantId = Optional.ofNullable(currentUser.getMerchantId()).orElseThrow(() -> new BusinessException("商家用户未绑定商家"));
            }
            service.queryFinanceLinePage(page, Optional.ofNullable(financeLine).orElse(new FinanceLine()), siteId, merchantId).getRecords();

            // 导出文件名称
            mv.addObject(NormalExcelConstants.FILE_NAME, "一对多订单示例");
            // 注解对象Class
            mv.addObject(NormalExcelConstants.CLASS, FinanceLine.class);
            // 自定义表格参数
            mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("自定义导出Excel内容标题", "what", "自定义Sheet名字"));
            // 导出数据列表
            mv.addObject(NormalExcelConstants.DATA_LIST, page.getRecords());
            return mv;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("查询提现行分页信息失败, " + e.getMessage());
        }

    }

}
